/**
 * 字符串转JSON对象
 * @param {String} jsonStr 对象字符串
 * @return {Object} 转换完的对象
 */
function stringToJSON(jsonStr) {
    if (jsonStr[0] == "[" && jsonStr[jsonStr.length - 1] == "]")
        return stringToJSONByArray(jsonStr);
    else
        return stringToJSONByOne(jsonStr);
    /**
     * 字符串转单个对象
     * @param {String} jsonStr 对象字符串
     * @return {Object} 转换后的对象
     */
    function stringToJSONByOne(jsonStr) {
        var obj = {};
        //获取每一项键值对的字符串
        var keyValArr = cusSplit(jsonStr, true);
        for (var i = 0; i < keyValArr.length; i++) {
            var curKeyVal = keyValArr[i];
            //获取name和value的字符串数组
            var nameAndVal = (function() {
                var arrayTemp = [];
                var tempVar = curKeyVal.trim();
                var startIndex = 0;
                arrayTemp.push(tempVar.substring(1, (startIndex = tempVar.indexOf(":")) - 1));
                arrayTemp.push(tempVar.substring(startIndex + 1, tempVar.length));
                return arrayTemp;
            }());
            var name = nameAndVal[0];
            var property = nameAndVal[1];
            //设置属性到对象上
            setProertyToObjOrArray(property, function(result) {
                obj[name] = result;
            });
        }
        return obj;
    }
    /**
     * 字符串转数组
     * @param {String} jsonStr 数组字符串
     * @returns {Object} 转换后的数组对象
     */
    function stringToJSONByArray(jsonStr) {
        var obj = [];
        var jsonArray;
        jsonArray = cusSplit(jsonStr, false);
        for (var i = 0; i < jsonArray.length; i++) {
            var curElement = jsonArray[i];
            setProertyToObjOrArray(curElement, function(result) {
                obj.push(result);
            });
        }
        return obj;
    }

    /**
     * 将json字符串的每一项存到数组中去
     * 如果是对象字符串则将每个键值对字符串存到数组中去
     * 如果是数组字符串则将每一项的字符串存到数组中去
     * @param {String} strVar json字符串
     * @param {Boolean} flag true是对象,false是数组
     * @return {Array} 处理后的数组对象
     */
    function cusSplit(strVar, flag) {
        var resultArray = [];
        var startIndex = 1;
        var endIndex = 0;
        while (true) {
            if (flag) {
                endIndex = strVar.indexOf("\":", endIndex) + 1;
                //判断是不是空对象
                if (endIndex == 0) {
                    resultArray.push({});
                    break;
                }
            }
            //判断属性值的类型
            var tempChar = strVar[endIndex += 1];
            //判断是不是对象
            if (tempChar == "{" || tempChar == "[") {
                endIndex = getObjectEndIndex(strVar, endIndex, strVar[endIndex] == "{") + 1;
                //判断是不是字符串
            } else if (tempChar == "\"") {
                var tempStrIndex = strVar.indexOf("\"", endIndex + 1);
                while (true) {
                    //判断是不是字符串属性值的结束
                    if (strVar[tempStrIndex - 1] != "\\") {
                        endIndex = tempStrIndex + 1;
                        break;
                    }
                    tempStrIndex = strVar.indexOf("\"", tempStrIndex + 1);
                }
            } else {
                var tempIndex = strVar.indexOf(",", endIndex);
                //判读是否到对象的结束
                if (tempIndex == -1) {
                    endIndex = strVar.indexOf(flag ? "}" : "]", endIndex);
                    resultArray.push(strVar.slice(startIndex, endIndex));
                    break;
                } else
                    endIndex = tempIndex;
            }
            resultArray.push(strVar.slice(startIndex, endIndex));
            //判断是否结束
            if (strVar[endIndex] == (flag ? "}" : "]"))
                break;
            startIndex = endIndex + 1;
        }
        return resultArray;
    }
    /**
     * 根据开始的位置开始找寻第一个json对象结束的索引
     * @param {String} jsonStrVar json字符串
     * @param {Number} startIndex 开始索引的位置
     * @param {Boolean} flag 是对象还是数组,true对象false数组
     * @return {Number} 对象字符串的结束索引
     */
    function getObjectEndIndex(jsonStrVar, startIndex, flag) {
        //对象结束的索引
        var resultIndex;
        //进行偏移的临时索引,最后需要将值赋给resultIndex变量
        var tempStrIndex;
        /**
         * @param {Number} startIndex 左括号(中括号)的索引
         * @param {Boolean} flag true对象false数组
         */
        function objectIndexProcess(startIndex, flag) {
            tempStrIndex = jsonStrVar.indexOf(flag ? "{" : "[", startIndex);
            resultIndex = tempStrIndex;
            if (tempStrIndex == -1)
                return;
            while (true) {
                if (flag) {
                    tempStrIndex = jsonStrVar.indexOf("\":", resultIndex) + 1;
                    //判断是不是空对象
                    if (tempStrIndex == 0) {
                        resultIndex += 1;
                        return;
                    }
                }
                //判断当前属性值的类型
                var tempVar = jsonStrVar[tempStrIndex += 1];
                //判断是不是对象
                if (tempVar == "{" || tempVar == "[")
                    objectIndexProcess(tempStrIndex, tempVar == "{");
                //判断是不是字符串
                else if (tempVar == "\"") {
                    tempEndIndex = jsonStrVar.indexOf("\"", tempStrIndex + 1);
                    while (true) {
                        //判断是不是字符串的结尾
                        if (jsonStrVar[tempEndIndex - 1] != "\\") {
                            tempStrIndex = tempEndIndex;
                            break;
                        }
                        tempEndIndex = jsonStrVar.indexOf("\"", tempEndIndex + 1);
                    }
                } else {
                    var first = jsonStrVar.indexOf(flag ? "}" : "]", tempStrIndex);
                    var second = jsonStrVar.indexOf(",", tempStrIndex);
                    //判断是不是最后一个属性值
                    if (second < first && second != -1)
                        tempStrIndex = jsonStrVar.indexOf(",", tempStrIndex);
                    else {
                        tempStrIndex = first;
                        resultIndex = tempStrIndex;
                        break;
                    }
                }
                //判断是不是到结尾了
                if (jsonStrVar[tempStrIndex + 1] == (flag ? "}" : "]")) {
                    resultIndex = (tempStrIndex += 1);
                    break;
                }
                resultIndex = tempStrIndex;
            }
        }
        objectIndexProcess(startIndex, flag);
        return resultIndex;
    }
    /**
     * 对属性值进行解析然后赋值给对应的对象或者数组
     * @param {String} curElement 属性值字符串
     * @param {Function} process 处理结果的回调函数
     */
    function setProertyToObjOrArray(curElement, process) {
        //判读是不是对象
        if (curElement[0] == "{" && curElement[curElement.length - 1] == "}") {
            process(stringToJSONByOne(curElement));
            //判读是不是数组
        } else if (curElement[0] == "[" && curElement[curElement.length - 1] == "]") {
            process(stringToJSONByArray(curElement));
            //判断是不是布尔类型
        } else if (curElement == "true" || curElement == "false") {
            process(curElement == "true");
            //判断是不是字符串
        } else if (curElement[0] == "\"" && curElement[curElement.length - 1] == "\"") {
            process(curElement.slice(1, curElement.length - 1));
        } else {
            process(Number(curElement));
        }
    }
}
